"""
分析历史管理器

功能：
- 记录债券分析历史
- 支持按债券代码和分析类型快速查询
- 提供统计分析功能
- 支持数据持久化

作者：System
创建时间：2025-01-13
"""

from typing import List, Dict, Optional
from datetime import datetime
import json
import os
from pathlib import Path
from collections import defaultdict


class AnalysisHistory:
    """分析历史管理器"""
    
    def __init__(self, storage_path: str = "cache/analysis_history.json"):
        """
        初始化分析历史管理器
        
        Args:
            storage_path: 分析历史存储路径
        """
        self.storage_path = storage_path
        self.history = {}  # {bond_code: [analysis_records]}
        self.load_history()
    
    def add_analysis(self, bond_code: str, analysis_type: str, result: dict, thread_id: Optional[str] = None) -> None:
        """
        添加一条分析记录
        
        Args:
            bond_code: 债券代码
            analysis_type: 分析类型（如 "credit", "terms", "macro", "value", "comparison"）
            result: 分析结果字典
            thread_id: 会话线程ID（可选）
        """
        if bond_code not in self.history:
            self.history[bond_code] = []
        
        record = {
            "type": analysis_type,
            "result": result,
            "timestamp": datetime.now().isoformat(),
            "thread_id": thread_id
        }
        
        self.history[bond_code].append(record)
        
        # 自动保存
        self.save_history()
    
    def get_latest_analysis(self, bond_code: str, analysis_type: Optional[str] = None) -> Optional[dict]:
        """
        获取最新的分析结果
        
        Args:
            bond_code: 债券代码
            analysis_type: 分析类型（可选，不指定则返回所有类型中最新的）
            
        Returns:
            最新的分析记录，如果没有则返回None
        """
        if bond_code not in self.history:
            return None
        
        records = self.history[bond_code]
        
        # 如果指定了分析类型，筛选出对应类型的记录
        if analysis_type:
            records = [r for r in records if r["type"] == analysis_type]
        
        if not records:
            return None
        
        # 返回时间戳最新的记录
        return max(records, key=lambda x: x["timestamp"])
    
    def get_all_analyses(self, bond_code: str, analysis_type: Optional[str] = None) -> List[dict]:
        """
        获取某个债券的所有分析记录
        
        Args:
            bond_code: 债券代码
            analysis_type: 分析类型（可选）
            
        Returns:
            分析记录列表，按时间倒序排列
        """
        if bond_code not in self.history:
            return []
        
        records = self.history[bond_code]
        
        # 如果指定了分析类型，筛选出对应类型的记录
        if analysis_type:
            records = [r for r in records if r["type"] == analysis_type]
        
        # 按时间倒序排列
        return sorted(records, key=lambda x: x["timestamp"], reverse=True)
    
    def get_analysis_count(self, bond_code: str, analysis_type: Optional[str] = None) -> int:
        """
        获取某个债券的分析次数
        
        Args:
            bond_code: 债券代码
            analysis_type: 分析类型（可选）
            
        Returns:
            分析次数
        """
        if bond_code not in self.history:
            return 0
        
        if analysis_type:
            return len([r for r in self.history[bond_code] if r["type"] == analysis_type])
        
        return len(self.history[bond_code])
    
    def get_frequently_analyzed_bonds(self, top_n: int = 10) -> List[tuple]:
        """
        获取分析次数最多的债券
        
        Args:
            top_n: 返回前N个债券（默认10个）
            
        Returns:
            [(bond_code, count), ...] 按次数降序排列
        """
        counts = [(code, len(records)) for code, records in self.history.items()]
        counts.sort(key=lambda x: x[1], reverse=True)
        return counts[:top_n]
    
    def get_analysis_types_summary(self, bond_code: Optional[str] = None) -> Dict[str, int]:
        """
        获取分析类型统计
        
        Args:
            bond_code: 债券代码（可选，不指定则统计所有债券）
            
        Returns:
            {analysis_type: count} 各类型分析次数
        """
        type_counts = defaultdict(int)
        
        if bond_code:
            # 统计指定债券的分析类型
            if bond_code in self.history:
                for record in self.history[bond_code]:
                    type_counts[record["type"]] += 1
        else:
            # 统计所有债券的分析类型
            for records in self.history.values():
                for record in records:
                    type_counts[record["type"]] += 1
        
        return dict(type_counts)
    
    def get_recent_analyses(self, days: int = 7, limit: int = 20) -> List[dict]:
        """
        获取最近的分析记录
        
        Args:
            days: 最近N天（默认7天）
            limit: 最多返回记录数（默认20条）
            
        Returns:
            分析记录列表，包含债券代码信息
        """
        from datetime import timedelta
        
        cutoff_time = datetime.now() - timedelta(days=days)
        recent_records = []
        
        for bond_code, records in self.history.items():
            for record in records:
                record_time = datetime.fromisoformat(record["timestamp"])
                if record_time >= cutoff_time:
                    # 添加债券代码信息
                    record_with_code = record.copy()
                    record_with_code["bond_code"] = bond_code
                    recent_records.append(record_with_code)
        
        # 按时间倒序排列
        recent_records.sort(key=lambda x: x["timestamp"], reverse=True)
        
        return recent_records[:limit]
    
    def search_analyses(self, keyword: str) -> List[dict]:
        """
        搜索分析记录
        
        Args:
            keyword: 搜索关键词
            
        Returns:
            匹配的分析记录列表
        """
        results = []
        keyword_lower = keyword.lower()
        
        for bond_code, records in self.history.items():
            # 搜索债券代码
            if keyword_lower in bond_code.lower():
                for record in records:
                    record_with_code = record.copy()
                    record_with_code["bond_code"] = bond_code
                    results.append(record_with_code)
                continue
            
            # 搜索分析结果内容
            for record in records:
                if keyword_lower in str(record).lower():
                    record_with_code = record.copy()
                    record_with_code["bond_code"] = bond_code
                    results.append(record_with_code)
        
        return results
    
    def delete_bond_history(self, bond_code: str) -> bool:
        """
        删除某个债券的所有历史记录
        
        Args:
            bond_code: 债券代码
            
        Returns:
            是否删除成功
        """
        if bond_code in self.history:
            del self.history[bond_code]
            self.save_history()
            return True
        return False
    
    def clear_old_records(self, days: int = 30) -> int:
        """
        清理过期的历史记录
        
        Args:
            days: 保留最近N天的记录（默认30天）
            
        Returns:
            清理的记录数
        """
        from datetime import timedelta
        
        cutoff_time = datetime.now() - timedelta(days=days)
        cleared_count = 0
        
        for bond_code in list(self.history.keys()):
            # 过滤掉过期的记录
            original_count = len(self.history[bond_code])
            self.history[bond_code] = [
                r for r in self.history[bond_code]
                if datetime.fromisoformat(r["timestamp"]) >= cutoff_time
            ]
            
            cleared_count += original_count - len(self.history[bond_code])
            
            # 如果该债券没有任何记录了，删除该键
            if not self.history[bond_code]:
                del self.history[bond_code]
        
        if cleared_count > 0:
            self.save_history()
        
        return cleared_count
    
    def save_history(self) -> None:
        """保存历史到文件"""
        try:
            # 确保目录存在
            Path(self.storage_path).parent.mkdir(parents=True, exist_ok=True)
            
            with open(self.storage_path, 'w', encoding='utf-8') as f:
                json.dump(self.history, f, ensure_ascii=False, indent=2)
        except Exception as e:
            print(f"保存分析历史失败: {e}")
    
    def load_history(self) -> None:
        """从文件加载历史"""
        try:
            if os.path.exists(self.storage_path):
                with open(self.storage_path, 'r', encoding='utf-8') as f:
                    self.history = json.load(f)
        except FileNotFoundError:
            pass
        except Exception as e:
            print(f"加载分析历史失败: {e}")
    
    def get_statistics(self) -> Dict:
        """
        获取统计信息
        
        Returns:
            包含统计信息的字典
        """
        total_bonds = len(self.history)
        total_analyses = sum(len(records) for records in self.history.values())
        
        return {
            "total_bonds": total_bonds,
            "total_analyses": total_analyses,
            "frequently_analyzed": self.get_frequently_analyzed_bonds(5),
            "analysis_types": self.get_analysis_types_summary()
        }


# 创建全局单例（可选）
_global_analysis_history = None

def get_analysis_history() -> AnalysisHistory:
    """
    获取全局分析历史管理器单例
    
    Returns:
        AnalysisHistory实例
    """
    global _global_analysis_history
    if _global_analysis_history is None:
        _global_analysis_history = AnalysisHistory()
    return _global_analysis_history